// @/api/chat.js
import request from '@/utils/request';

export function getMessage(sessionId) {
    return request.get('/llm/get', {
        params: { sessionId }
    });
}

export function sendMessage(model, prompt, sessionId, think = true) {
    return request.get('/llm/chat', {
        params: {
            model,
            prompt,
            sessionId,
            think
        }
    });
}

export function newSession() {
    return request.get('/llm/new')
}

export function listSession() {
    return request.get('/llm/list')
}

export function deleteSession(data) {
    console.debug()
    let sessionId = data.params.sessionId
    return request.get('/llm/delete', {
        params: { sessionId }
    });
}

export function startStreamReply(sessionId, onMessage, onError, onComplete) {
    const token = localStorage.getItem('token');
    if (!token) {
        if (onError) onError(new Error('No authentication token found'));
        return {
            close: () => {},
            CLOSED: 2,
            CONNECTING: 0,
            OPEN: 1,
            readyState: 0
        };
    }
    
    const url = `${process.env.VUE_APP_URL}/llm/reply?sessionId=${sessionId}`;
    
    // Use fetch API for streaming with proper headers - EventSource doesn't support custom headers
    const controller = new AbortController();
    const signal = controller.signal;
    
    fetch(url, {
        method: 'GET',
        headers: {
            'Authorization': `Bearer ${token}`,
            'Accept': 'text/event-stream',
            'Cache-Control': 'no-cache'
        },
        signal
    })
    .then(response => {
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        
        // Check if response body is readable
        if (!response.body) {
            if (onError) onError(new Error('Response body is not readable'));
            return;
        }
        
        const reader = response.body.getReader();
        const decoder = new TextDecoder('utf-8');
        let buffer = '';
        
        function read() {
            reader.read().then(({ done, value }) => {
                if (done) {
                    if (onComplete) onComplete();
                    return;
                }
                
                if (!value) {
                    read(); // Continue reading
                    return;
                }
                
                buffer += decoder.decode(value, { stream: true });
                const lines = buffer.split(/\r\n|\n|\r/);
                buffer = lines.pop();
                
                for (const line of lines) {
                    if (line.startsWith('data:')) {
                        // Handle data lines (might not have space after colon)
                        const data = line.slice(5).trim(); // Remove 'data:' and trim
                        if (onMessage) {
                            onMessage({ data });
                        }
                    } else if (line.startsWith('event:')) {
                        // Event line - ignore for now
                    } else if (line === '') {
                        // Empty/heartbeat line - ignore
                    } else if (line.startsWith(':')) {
                        // Comment line - ignore
                    } else if (line.trim() !== '') {
                        // Handle lines that don't have a prefix but contain data
                        if (onMessage) {
                            onMessage({ data: line });
                        }
                    }
                }
                
                read(); // Continue reading
            }).catch(err => {
                console.error('Reader error:', err);
                if (err.name !== 'AbortError') {
                    if (onError) onError(err);
                }
            });
        }
        
        read(); // Start reading
    })
    .catch(err => {
        if (err.name !== 'AbortError') {
            if (onError) onError(err);
        }
    });
    
    // Return an object with close method to match EventSource interface
    return {
        close: () => controller.abort(),
        CLOSED: 2,
        CONNECTING: 0,
        OPEN: 1,
        readyState: 1
    };
}